#pragma once

#include "Log.h"
#include <functional>
#include <iostream>
#include <string>
#include <unistd.h>
#include <cstring>
#include <cerrno>

#define IO_BUFFER_SIZE 1024

void ioService(int sockfd) {
    char buffer[IO_BUFFER_SIZE] = {};
    while (true) { // 事实上服务端是不会与客户端一直建立联系的，应该是处理完客户端发来的任务就断开连接，这里为了方便测试就写了死循环
        // 因为TCP通信是面向字节流的，所以可以用read和write来进行读取和发送数据
        ssize_t n = read(sockfd, buffer, IO_BUFFER_SIZE - 1); 
        if (n > 0) { // 成功读取到客户端发来的数据
            buffer[n] = '\0'; // 我们目前将得到的数据当字符串处理
            logMessage(NORMAL, "receive message %s from socket %d", buffer, sockfd);
            std::string response = "[server]echo# ";
            response += std::string(buffer);

            write(sockfd, response.c_str(), response.size());
        }
        else if (n == 0) { // 客户端关闭
            logMessage(NORMAL, "client quit, ioService quit too! sockfd: %d", sockfd);
            break; // 退出循环
        }
        else { // 发生未知错误
            // 与客户端间的通信发生错误了不需要让服务器直接宕机
            // 终止与客户端之间的连接就行
            logMessage(ERROR, "ioService err! pid: %d sockfd: %d %s", getpid(), sockfd, strerror(errno));
            break;
        }
    }

    close(sockfd); // 结束了与客户端的通信需要关闭与之通信的套接字，避免fd泄漏
}

class Task {
private:
    using func_t = std::function<void(int)>;

private:
    int _sockfd; // 通信用fd
    func_t _call_back_function;

public:
    Task() = default;

    Task(const int& sockfd, const func_t& call_back_function)
        : _sockfd(sockfd)
        , _call_back_function(call_back_function)
    {}

public:
    void operator()() {
        //! 如果你的函数声明写了有返回值，但你没有返回，OS会直接发你一个段错误，你给我小心了
        //! 看半天不知道段错误哪来的，结果就这一个返回值？
        //! 你不会编译器报错吗？
        _call_back_function(_sockfd);
    }
};
